
module D_mem(address_in,data_in,data_out,Sel_W,Sel_R,clk,rst);

input [7:0] address_in;
input [7:0] data_in;
input Sel_W;  //1->write
input Sel_R;  //1->read	
output [7:0] data_out;

input clk;
input rst;

wire [7:0] ro1,ro2,ro3,ro4,ro5,ro6,ro7,ro8,
	   ro9,ro10,ro11,ro12,ro13,ro14,ro15,ro16,
	   ro17,ro18,ro19,ro20,ro21,ro22,ro23,ro24,
	   ro25,ro26,ro27,ro28,ro29,ro30,ro31,ro32;

Register_8bit rr1(clk,rst,data_in,ro1,{Sel_W,Sel_W});
Register_8bit rr2(clk,rst,data_in,ro2,{Sel_W,Sel_W});
Register_8bit rr3(clk,rst,data_in,ro3,{Sel_W,Sel_W});
Register_8bit rr4(clk,rst,data_in,ro4,{Sel_W,Sel_W});
Register_8bit rr5(clk,rst,data_in,ro5,{Sel_W,Sel_W});
Register_8bit rr6(clk,rst,data_in,ro6,{Sel_W,Sel_W});
Register_8bit rr7(clk,rst,data_in,ro7,{Sel_W,Sel_W});
Register_8bit rr8(clk,rst,data_in,ro8,{Sel_W,Sel_W});
Register_8bit rr9(clk,rst,data_in,ro9,{Sel_W,Sel_W});
Register_8bit rr10(clk,rst,data_in,ro10,{Sel_W,Sel_W});
Register_8bit rr11(clk,rst,data_in,ro11,{Sel_W,Sel_W});
Register_8bit rr12(clk,rst,data_in,ro12,{Sel_W,Sel_W});
Register_8bit rr13(clk,rst,data_in,ro13,{Sel_W,Sel_W});
Register_8bit rr14(clk,rst,data_in,ro14,{Sel_W,Sel_W});
Register_8bit rr15(clk,rst,data_in,ro15,{Sel_W,Sel_W});
Register_8bit rr16(clk,rst,data_in,ro16,{Sel_W,Sel_W});
Register_8bit rr17(clk,rst,data_in,ro17,{Sel_W,Sel_W});
Register_8bit rr18(clk,rst,data_in,ro18,{Sel_W,Sel_W});
Register_8bit rr19(clk,rst,data_in,ro19,{Sel_W,Sel_W});
Register_8bit rr20(clk,rst,data_in,ro20,{Sel_W,Sel_W});
Register_8bit rr21(clk,rst,data_in,ro21,{Sel_W,Sel_W});
Register_8bit rr22(clk,rst,data_in,ro22,{Sel_W,Sel_W});
Register_8bit rr23(clk,rst,data_in,ro23,{Sel_W,Sel_W});
Register_8bit rr24(clk,rst,data_in,ro24,{Sel_W,Sel_W});
Register_8bit rr25(clk,rst,data_in,ro25,{Sel_W,Sel_W});
Register_8bit rr26(clk,rst,data_in,ro26,{Sel_W,Sel_W});
Register_8bit rr27(clk,rst,data_in,ro27,{Sel_W,Sel_W});
Register_8bit rr28(clk,rst,data_in,ro28,{Sel_W,Sel_W});
Register_8bit rr29(clk,rst,data_in,ro29,{Sel_W,Sel_W});
Register_8bit rr30(clk,rst,data_in,ro30,{Sel_W,Sel_W});
Register_8bit rr31(clk,rst,data_in,ro31,{Sel_W,Sel_W});
Register_8bit rr32(clk,rst,data_in,ro32,{Sel_W,Sel_W});

MUX32to1_8bit mm1(ro1,ro2,ro3,ro4,ro5,ro6,ro7,ro8,
	          ro9,ro10,ro11,ro12,ro13,ro14,ro15,ro16,
	          ro17,ro18,ro19,ro20,ro21,ro22,ro23,ro24,
	          ro25,ro26,ro27,ro28,ro29,ro30,ro31,ro32,
	          data_out,{address_in[6:3]});


endmodule

module Register_8bit(
  clk,
  rst,
  d,
  q,
  sel
 );
  
  input clk, rst;
  input [7:0]d;
  input [1:0]sel; // 00:no change, 01:right shift, 10:left shift, 11:input
  output [7:0]q;
  
  wire [7:0]qq;
  wire [7:0]nq;
  
  dflipflop d1(clk, rst, d[0], qq[0], nq[0]);
  dflipflop d2(clk, rst, d[1], qq[1], nq[1]);
  dflipflop d3(clk, rst, d[2], qq[2], nq[2]);
  dflipflop d4(clk, rst, d[3], qq[3], nq[3]);
  dflipflop d5(clk, rst, d[4], qq[4], nq[4]);
  dflipflop d6(clk, rst, d[5], qq[5], nq[5]);
  dflipflop d7(clk, rst, d[6], qq[6], nq[6]);
  dflipflop d8(clk, rst, d[7], qq[7], nq[7]);
  
  MUX4to1_8bit m0(qq, {qq[0],qq[7:1]}, {qq[6:0],qq[7]}, d, q, sel);
  
endmodule

module dflipflop(
  clk,
  rst, 
  input1,
  output1,
  noutput1
);

input input1, clk, rst;
output output1, noutput1;

wire w1, w2, w3, w4;
wire  input2;

and a1(input2, input1, rst);

nand n1(w1, w4, w2);
nand n2(w2, w1, clk);
nand n3(w3, w2, clk, w4);
nand n4(w4, w3, input2);

nand n5(output1, w2, noutput1);
nand n6(noutput1, output1, w3);


endmodule

module MUX4to1_1bit(
  input0,
  input1,
  input2,
  input3,
  output0,
  sel,
  on
);

input input0, 
      input1,
      input2,
      input3;
input [1:0]sel;
input on;
output output0;

wire [3:0]w1;

and a0(w1[0], input0, ~sel[0], ~sel[1], on);
and a1(w1[1], input1, sel[0], ~sel[1], on);
and a2(w1[2], input2, ~sel[0], sel[1], on);
and a3(w1[3], input3, sel[0], sel[1], on);

or o0(output0, w1[0], w1[1], w1[2], w1[3]);

endmodule

module MUX4to1_8bit(
  input0,
  input1,
  input2,
  input3,
  output0,
  sel
);

input [7:0]input0, input1, input2, input3;
input [1:0]sel;
output [7:0]output0;

MUX4to1_1bit m0(input0[0], input1[0], input2[0], input3[0], output0[0], sel, 1'b1);
MUX4to1_1bit m1(input0[1], input1[1], input2[1], input3[1], output0[1], sel, 1'b1);
MUX4to1_1bit m2(input0[2], input1[2], input2[2], input3[2], output0[2], sel, 1'b1);
MUX4to1_1bit m3(input0[3], input1[3], input2[3], input3[3], output0[3], sel, 1'b1);
MUX4to1_1bit m4(input0[4], input1[4], input2[4], input3[4], output0[4], sel, 1'b1);
MUX4to1_1bit m5(input0[5], input1[5], input2[5], input3[5], output0[5], sel, 1'b1);
MUX4to1_1bit m6(input0[6], input1[6], input2[6], input3[6], output0[6], sel, 1'b1);
MUX4to1_1bit m7(input0[7], input1[7], input2[7], input3[7], output0[7], sel, 1'b1);



endmodule

module DECODER_4bit(in, out);
input [3:0] in;
output [15:0] out;
wire [7:0] DecodedData;
wire Nin;

assign Nin = ~in[3];
DECODER_3bit Dec3(in[2:0], DecodedData[7:0]);

and(out[15], in[3], DecodedData[7]);
and(out[14], in[3], DecodedData[6]);
and(out[13], in[3], DecodedData[5]);
and(out[12], in[3], DecodedData[4]);
and(out[11], in[3], DecodedData[3]);
and(out[10], in[3], DecodedData[2]);
and(out[9], in[3], DecodedData[1]);
and(out[8], in[3], DecodedData[0]);

and(out[7], Nin, DecodedData[7]);
and(out[6], Nin, DecodedData[6]);
and(out[5], Nin, DecodedData[5]);
and(out[4], Nin, DecodedData[4]);
and(out[3], Nin, DecodedData[3]);
and(out[2], Nin, DecodedData[2]);
and(out[1], Nin, DecodedData[1]);
and(out[0], Nin, DecodedData[0]);


endmodule


module DECODER_3bit(in, out);
input [2:0] in;
output [7:0] out;
wire [3:0] DecodedData;
wire Nin;
assign Nin = ~in[2];
DECODER_2bit Dec2(in[1:0], DecodedData[3:0]);


and(out[7], in[2], DecodedData[3]);
and(out[6], in[2], DecodedData[2]);
and(out[5], in[2], DecodedData[1]);
and(out[4], in[2], DecodedData[0]);


and(out[3], Nin, DecodedData[3]);
and(out[2], Nin, DecodedData[2]);
and(out[1], Nin, DecodedData[1]);
and(out[0], Nin, DecodedData[0]);

endmodule

module DECODER_2bit(in, out);
input [1:0] in;
output [3:0] out;
wire [1:0] Nin;

assign Nin = ~in;

and a1(out[0], Nin[1], Nin[0]);
and a2(out[1], Nin[1], in[0]);
and a3(out[2], in[1], Nin[0]);
and a4(out[3], in[1], in[0]);

endmodule

module MUX8to1_1bit(
  input0,
  input1,
  input2,
  input3,
  input4,
  input5,
  input6,
  input7,
  output0,
  sel,
  on
);

input input0,
      input1,
      input2,
      input3,
      input4,
      input5,
      input6,
      input7;
input [2:0]sel;
input on;
output output0;


wire [1:0]w1;
wire [1:0]on1;
and a0(on1[0], ~sel[2], on);
and a1(on1[1], sel[2], on);

MUX4to1_1bit m0(input0, input1, input2, input3, w1[0], sel[1:0], on1[0]);
MUX4to1_1bit m1(input4, input5, input6, input7, w1[1], sel[1:0], on1[1]);

or o1(output0, w1[0], w1[1]);

endmodule

module MUX16to1_1bit(
  input0,
  input1,
  input2,
  input3,
  input4,
  input5,
  input6,
  input7,
  input8,
  input9,
  input10,
  input11,
  input12,
  input13,
  input14,
  input15,
  output0,
  sel,
  on
);

input input0,
      input1,
      input2,
      input3,
      input4,
      input5,
      input6,
      input7,
      input8,
      input9,
      input10,
      input11,
      input12,
      input13,
      input14,
      input15;
input [3:0]sel;
input on;
output output0;

wire [1:0]w1;
wire [1:0]on1;
and a0(on1[0], ~sel[3], on);
and a1(on1[1], sel[3], on);

MUX8to1_1bit m0(input0, input1, input2, input3, input4, input5, input6, input7, w1[0], sel[2:0], on1[0]);
MUX8to1_1bit m1(input8, input9, input10, input11, input12, input13, input14, input15, w1[1], sel[2:0], on1[1]);

or o1(output0, w1[0], w1[1]);

endmodule

module MUX32to1_1bit(
  input0,
  input1,
  input2,
  input3,
  input4,
  input5,
  input6,
  input7,
  input8,
  input9,
  input10,
  input11,
  input12,
  input13,
  input14,
  input15,
  input16,
  input17,
  input18,
  input19,
  input20,
  input21,
  input22,
  input23,
  input24,
  input25,
  input26,
  input27,
  input28,
  input29,
  input30,
  input31,
  output0,
  sel,
  on
);

input input0,
      input1,
      input2,
      input3,
      input4,
      input5,
      input6,
      input7,
      input8,
      input9,
      input10,
      input11,
      input12,
      input13,
      input14,
      input15,
      input16,
      input17,
      input18,
      input19,
      input20,
      input21,
      input22,
      input23,
      input24,
      input25,
      input26,
      input27,
      input28,
      input29,
      input30,
      input31;
input [4:0]sel;
input on;
output output0;

wire [1:0]w1;
wire [1:0]on1;
and a0(on1[0], ~sel[4], on);
and a1(on1[1], sel[4], on);

MUX16to1_1bit m0(input0, input1, input2, input3, input4, input5, input6, input7, input8, input9, input10, input11, input12, input13, input14, input15, w1[0], sel[3:0], on1[0]);
MUX16to1_1bit m1(input16, input17, input18, input19, input20, input21, input22, input23, input24, input25, input26, input27, input28, input29, input30, input31, w1[1], sel[3:0], on1[1]);

or o1(output0, w1[0], w1[1]);

endmodule

module MUX32to1_8bit(
  input0,
  input1,
  input2,
  input3,
  input4,
  input5,
  input6,
  input7,
  input8,
  input9,
  input10,
  input11,
  input12,
  input13,
  input14,
  input15,
  input16,
  input17,
  input18,
  input19,
  input20,
  input21,
  input22,
  input23,
  input24,
  input25,
  input26,
  input27,
  input28,
  input29,
  input30,
  input31,
  output1,
  sel
);

input [7:0]input0,
      input1,
      input2,
      input3,
      input4,
      input5,
      input6,
      input7,
      input8,
      input9,
      input10,
      input11,
      input12,
      input13,
      input14,
      input15,
      input16,
      input17,
      input18,
      input19,
      input20,
      input21,
      input22,
      input23,
      input24,
      input25,
      input26,
      input27,
      input28,
      input29,
      input30,
      input31;
input [4:0]sel;
output [7:0]output1;


MUX32to1_1bit m0(input0[0], input1[0], input2[0], input3[0], input4[0], input5[0], input6[0], input7[0], input8[0], input9[0], input10[0], input11[0], input12[0], input13[0], input14[0], input15[0], input16[0], input17[0], input18[0], input19[0], input20[0], input21[0], input22[0], input23[0], input24[0], input25[0], input26[0], input27[0], input28[0], input29[0], input30[0], input31[0], output1[0], sel, 1'b1);
MUX32to1_1bit m1(input0[1], input1[1], input2[1], input3[1], input4[1], input5[1], input6[1], input7[1], input8[1], input9[1], input10[1], input11[1], input12[1], input13[1], input14[1], input15[1], input16[1], input17[1], input18[1], input19[1], input20[1], input21[1], input22[1], input23[1], input24[1], input25[1], input26[1], input27[1], input28[1], input29[1], input30[1], input31[1], output1[1], sel, 1'b1);
MUX32to1_1bit m2(input0[2], input1[2], input2[2], input3[2], input4[2], input5[2], input6[2], input7[2], input8[2], input9[2], input10[2], input11[2], input12[2], input13[2], input14[2], input15[2], input16[2], input17[2], input18[2], input19[2], input20[2], input21[2], input22[2], input23[2], input24[2], input25[2], input26[2], input27[2], input28[2], input29[2], input30[2], input31[2], output1[2], sel, 1'b1);
MUX32to1_1bit m3(input0[3], input1[3], input2[3], input3[3], input4[3], input5[3], input6[3], input7[3], input8[3], input9[3], input10[3], input11[3], input12[3], input13[3], input14[3], input15[3], input16[3], input17[3], input18[3], input19[3], input20[3], input21[3], input22[3], input23[3], input24[3], input25[3], input26[3], input27[3], input28[3], input29[3], input30[3], input31[3], output1[3], sel, 1'b1);
MUX32to1_1bit m4(input0[4], input1[4], input2[4], input3[4], input4[4], input5[4], input6[4], input7[4], input8[4], input9[4], input10[4], input11[4], input12[4], input13[4], input14[4], input15[4], input16[4], input17[4], input18[4], input19[4], input20[4], input21[4], input22[4], input23[4], input24[4], input25[4], input26[4], input27[4], input28[4], input29[4], input30[4], input31[4], output1[4], sel, 1'b1);
MUX32to1_1bit m5(input0[5], input1[5], input2[5], input3[5], input4[5], input5[5], input6[5], input7[5], input8[5], input9[5], input10[5], input11[5], input12[5], input13[5], input14[5], input15[5], input16[5], input17[5], input18[5], input19[5], input20[5], input21[5], input22[5], input23[5], input24[5], input25[5], input26[5], input27[5], input28[5], input29[5], input30[5], input31[5], output1[5], sel, 1'b1);
MUX32to1_1bit m6(input0[6], input1[6], input2[6], input3[6], input4[6], input5[6], input6[6], input7[6], input8[6], input9[6], input10[6], input11[6], input12[6], input13[6], input14[6], input15[6], input16[6], input17[6], input18[6], input19[6], input20[6], input21[6], input22[6], input23[6], input24[6], input25[6], input26[6], input27[6], input28[6], input29[6], input30[6], input31[6], output1[6], sel, 1'b1);
MUX32to1_1bit m7(input0[7], input1[7], input2[7], input3[7], input4[7], input5[7], input6[7], input7[7], input8[7], input9[7], input10[7], input11[7], input12[7], input13[7], input14[7], input15[7], input16[7], input17[7], input18[7], input19[7], input20[7], input21[7], input22[7], input23[7], input24[7], input25[7], input26[7], input27[7], input28[7], input29[7], input30[7], input31[7], output1[7], sel, 1'b1);



endmodule
